#ifndef _HYPRILNK_H
#define _HYPRILNK_H


class hyper_link : public CString 
{
public:
	hyper_link(LPCTSTR ptr_link = NULL) 
		: CString(ptr_link) 
	{ 
	}

	~hyper_link() 
	{ 
	}

	const hyper_link& operator=(LPCTSTR lpsz) 
	{
		CString::operator=(lpsz);

		return *this;
	}

	operator LPCTSTR() 
	{
		return CString::operator LPCTSTR(); 
	}

	virtual HINSTANCE navigate() 
	{
		return IsEmpty() ? NULL : go_to_url(*this, SW_SHOWNORMAL);
	}

	LONG get_reg_key(HKEY key, LPCTSTR subkey, LPTSTR ret_data)
	{
		HKEY hkey;
		LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey);

		if (retval == ERROR_SUCCESS) 
		{
			long datasize = MAX_PATH;
			TCHAR data[MAX_PATH];
			RegQueryValue(hkey, NULL, data, &datasize);
			lstrcpy(ret_data,data);
			RegCloseKey(hkey);
		}

		return retval;
	}

	void report_error(int error)
	{
		CString str;
		switch (error) 
		{
		case 0:                       str = "The operating system is out\nof memory or resources."; break;
		case SE_ERR_PNF:              str = "The specified path was not found."; break;
		case SE_ERR_FNF:              str = "The specified file was not found."; break;
		case ERROR_BAD_FORMAT:        str = "The .EXE file is invalid\n(non-Win32 .EXE or error in .EXE image)."; break;
		case SE_ERR_ACCESSDENIED:     str = "The operating system denied\naccess to the specified file."; break;
		case SE_ERR_ASSOCINCOMPLETE:  str = "The filename association is\nincomplete or invalid."; break;
		case SE_ERR_DDEBUSY:          str = "The DDE transaction could not\nbe completed because other DDE transactions\nwere being processed."; break;
		case SE_ERR_DDEFAIL:          str = "The DDE transaction failed."; break;
		case SE_ERR_DDETIMEOUT:       str = "The DDE transaction could not\nbe completed because the request timed out."; break;
		case SE_ERR_DLLNOTFOUND:      str = "The specified dynamic-link library was not found."; break;
		case SE_ERR_NOASSOC:          str = "There is no application associated\nwith the given filename extension."; break;
		case SE_ERR_OOM:              str = "There was not enough memory to complete the operation."; break;
		case SE_ERR_SHARE:            str = "A sharing violation occurred. ";
		default:                      str.Format(_T("Unknown Error (%d) occurred."), error); break;
		}
		str = _T("Unable to open hyperlink:\n\n") + str;
		TRACE(str);
		//AfxMessageBox(str, MB_ICONEXCLAMATION | MB_OK);
	}

	HINSTANCE go_to_url(LPCTSTR url, int show_cmd)
	{
		TCHAR key[MAX_PATH + MAX_PATH];

		/// First try ShellExecute()
		HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, show_cmd);

		/// If it failed, get the .htm regkey and lookup the program
		if ((UINT)result <= HINSTANCE_ERROR) 
		{
			if (get_reg_key(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) 
			{
				lstrcat(key, _T("\\shell\\open\\command"));

				if (get_reg_key(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) 
				{
					TCHAR *pos;
					pos = _tcsstr(key, _T("\"%1\""));
					if (pos == NULL) 
					{									   /// No quotes found
						pos = _tcsstr(key, _T("%1"));      /// Check for %1, without quotes 
						if (pos == NULL)                   /// No parameter at all...
							pos = key+lstrlen(key)-1;
						else
							*pos = '\0';                   /// Remove the parameter
					}
					else
						*pos = '\0';                       /// Remove the parameter

					lstrcat(pos, _T(" "));
					lstrcat(pos, url);

					USES_CONVERSION;
					result = (HINSTANCE) WinExec(T2A(key),show_cmd);
				}
			}
		}
		else
		{
			report_error((int)result);
		}

		return result;
	}
};

#endif
